#ifndef __C_ARCH_BITOPS_H__
#define __C_ARCH_BITOPS_H__

#include "std/std.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifdef VIEWS_SMP_ENABLED
#define LOCK_PREFIX "lock ; "
#else
#define LOCK_PREFIX ""
#endif

// bit operations
static inline void set_bit(int nr, volatile void * addr)
{
#ifndef TEST_DBG_WIN32
	__asm__ __volatile__( LOCK_PREFIX
		"btsl %1,%0"
		:"=m" ((*(volatile long *) addr))
		:"Ir" (nr));
#endif
}

static inline void clear_bit(int nr, volatile void * addr)
{
#ifndef TEST_DBG_WIN32
	__asm__ __volatile__( LOCK_PREFIX
		"btrl %1,%0"
		:"=m" ((*(volatile long *) addr))
		:"Ir" (nr));
#endif
}

static inline void change_bit(int nr, volatile void * addr)
{
#ifndef TEST_DBG_WIN32
	__asm__ __volatile__( LOCK_PREFIX
		"btcl %1,%0"
		:"=m" ((*(volatile long *) addr))
		:"Ir" (nr));
#endif
}

static inline int test_and_set_bit(int nr, volatile void * addr)
{
#ifdef TEST_DBG_WIN32
	return 0;
#else
	int oldbit;

	__asm__ __volatile__( LOCK_PREFIX
		"btsl %2,%1\n\tsbbl %0,%0"
		:"=r" (oldbit),"=m" ((*(volatile long *) addr))
		:"Ir" (nr) : "memory");
	return oldbit;
#endif
}

static inline int test_and_clear_bit(int nr, volatile void * addr)
{
#ifdef TEST_DBG_WIN32
	return 0;
#else
	int oldbit;

	__asm__ __volatile__( LOCK_PREFIX
		"btrl %2,%1\n\tsbbl %0,%0"
		:"=r" (oldbit),"=m" ((*(volatile long *) addr))
		:"Ir" (nr) : "memory");
	return oldbit;
#endif
}

static inline int test_and_change_bit(int nr, volatile void * addr)
{
#ifdef TEST_DBG_WIN32
	return 0;
#else
	int oldbit;

	__asm__ __volatile__( LOCK_PREFIX
		"btcl %2,%1\n\tsbbl %0,%0"
		:"=r" (oldbit),"=m" ((*(volatile long *) addr))
		:"Ir" (nr) : "memory");
	return oldbit;
#endif
}

#ifdef __cplusplus
}
#endif
#endif
/* EOF */
